package server;

import common.DataExchange;
import common.domain.ExamQuestions;
import common.domain.Student;
import common.domain.StudentMessage;
import common.dao.*;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import static common.Constance.*;

/**
 * @author LinLe
 * @create 2020-12-23 20:57
 */
public class StudentExamSysServer {
    //线程池
    private Executor pool = Executors.newCachedThreadPool();
    //存储学生信息
    private HashMap<String, Student> stuMap = new HashMap<>();
    //存储考题信息
    private Set<ExamQuestions> examMap = new HashSet<>();
    private int port;
    //对于结束线程的判断
    private boolean flag ;
    {
        stuMap.put("linle",new Student("linle","123456"));
        stuMap.put("senna",new Student("senna","123456"));
        examMap.add(new ExamQuestions("下列四个测量数据，用最小刻度是分米的刻度尺测量的是( )",
                "A．0.00158千米    B．5.0米 C．7.26分米    D．32毫米",20,"A"));
        examMap.add(new ExamQuestions("我国自主研制的首个目标飞行器“天宫一号”发射到正常轨道后将会与地球运动同步，根据地球自转的运动方向判断，“天宫一号”的运动方向应为()",
                "A．自东向西    B．自南向北C．顺时针    D．逆时针",20,"D"));
        examMap.add(new ExamQuestions("下列关于太阳黑子的说法正确的是( )",
                "A．通常把太阳黑子数出现最多的年份称为太阳活动峰年   B．太阳黑子不会对地球带来任何影响   C．现太阳黑子的地方是因为温度比周围高  D．对太阳黑子的预报和观测没有科学意义\n",20,"A"));
        examMap.add(new ExamQuestions("对于一只生活在田野中的蝗虫来说，它的生活环境是指( )",
                "A．田野中的植物和蛇、蛙等动物  B．阳光、空气、温度、水分等非生物因素  C．田野里的其他蝗虫  D．上述对象均是其生活环境",20,"D"));
        examMap.add(new ExamQuestions("据目前所知，只有地球上有高级智慧生命。下列有关地球所处的宇宙环境稳定的原因的说法中，错误的是( )",
                "A．太阳光照条件较稳定  B．八大行星的公转方向相同  C．地球的体积和质量适当  D．八大行星的公转轨道面几乎在同一平面上",20,"C"));
    }
    public StudentExamSysServer(int port) {
        this.port = port;
    }
    
    //开始运行服务器
    public void start() throws IOException {
        System.out.println("服务器正在启动等待连接..........");
        //开启服务器端口
        ServerSocket ss = new ServerSocket(SERVER_PORT);
        //接收客户端的连接
        while(true){
            Socket s = ss.accept();
            handleClientSocket(s);
        }
    }
    //利用Executor来运行线程
    private void handleClientSocket(Socket s) {
        pool.execute(new ClientHandle(s));
    }
    
    //实现runnable，重写run方法
    class ClientHandle implements Runnable {
        //客户端的Socket
        private Socket s ;
        //消息处理对象，里面有input等流对象
        private DataExchange de;
        public ClientHandle(Socket s) {
            this.s = s;
        }
        @Override
        public void run() {
            flag = true;
            System.out.println("正在处理来自 "+ s.getRemoteSocketAddress() + " 的连接");
            try {
                de = new DataExchange(s);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //处理用户名
            StudentMessage sm = null;
            String userName = null;
            String password = null;
            while(flag){
                try {
                    sm = de.receiveStudentMessage();
                    userName = sm.getStudent().getName();
                    password = sm.getStudent().getPassword();
                    String smMessage = sm.getMessage();
    
                    //若是managerCheck，就进入管理系统验证
                    if (MANAGE_CHECK.equalsIgnoreCase(smMessage)) {
                        //判断用户名与密码的准确
                        if("admin".equalsIgnoreCase(userName) &&
                                "123456".equalsIgnoreCase(password)){
                            de.sendString("SUCCESS");
                            //开始进入管理系统
                            manageSystem(de);
                        }else{
                            de.sendString("FAIL");
                        }
                    }else if(USER_CHECK.equalsIgnoreCase(smMessage)){
                     
                        //否则进入学员系统并验证
                        if(stuMap.size() == 0 ||  !stuMap.containsKey(userName) ||
                                !stuMap.get(userName).getPassword().equalsIgnoreCase( password)){
                            de.sendString("FAIL");
                        }
                        else{
                            de.sendString("SUCCESS");
                            studentSystem(de);
                        }
                    }else {
                        flag = false;
                    }
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                    de.close();
                    flag = false;
                }
            }
            
           
        }
        //---------------------------学员系统-----------------------------
        private void studentSystem(DataExchange de) {
            while(flag){
                String  message = null;
                StuInformationOperator ioi = null;
                ExamInformationOperator eio = null;
                try {
                    message = de.receiveString();
                    //是stuManagerCheck就进入学员信息管理
                    if(STU_MODEL.equalsIgnoreCase(message)){
                        //学员信息管理
                        StuUserOperator suo = new StuUserOperator(stuMap);
                        handleStuModel(suo);
                    } else if(EXAM_MODEL.equalsIgnoreCase(message)){//进入考题管理
                        handleExamModel();
                    }else {
                        flag = false;
                    }
                } catch (Exception e) {
                    this.de.close();
                    e.printStackTrace();
                    flag = false;
                }
        
            }
        }
    
        private void handleExamModel() throws IOException, ClassNotFoundException {
            while(true){
                String message = de.receiveString();
                switch (message){
                    case START_TEST:
                        int num = 5;
                        Set<ExamQuestions> paper = new HashSet<>();
                        ArrayList<ExamQuestions> questions = new ArrayList<>(examMap);
                        while(num  != paper.size() ){
                            paper.add(questions.get(paper.size()));
                        }
                        de.sendSet(paper);
                        Student student = de.receiveStudent();
                        stuMap.put(student.getName(),student);
                        break;
                    case "bye": return;
                }
            }
        }
    
        private void handleStuModel(StuUserOperator suo ) throws IOException, ClassNotFoundException {
            while(true){
                String message = de.receiveString();
                switch (message){
                    case "changePassword":
                        suo.changePassword(de);break;
                    case "bye": return;
                }
            }
            
        }
        //---------------------------管理员系统-----------------------------
        private void  manageSystem(DataExchange de){
            while(flag){
                String  message = null;
                StuInformationOperator ioi = null;
                ExamInformationOperator eio = null;
                try {
                    message = this.de.receiveString();
                    //是stuManagerCheck就进入学员信息管理
                    if(STU_MANAGE_CHECK.equalsIgnoreCase(message)){
                        ioi = new StuInformationOperator(stuMap);
                        //学员信息管理
                        handleStuManage(ioi);
                    } else if(EXAM_TEST_CHECK.equalsIgnoreCase(message)){//进入考题管理
                        eio = new ExamInformationOperator(examMap);
                        handleExamQuestions(eio);
                    }else{
                        flag = false;
                    }
                } catch (Exception e) {
                    this.de.close();
                    e.printStackTrace();
                    return;
                }
        
            }
        }
        //考题管理
        private void handleExamQuestions( ExamInformationOperator eio ) throws IOException, ClassNotFoundException {
            while(true){
                String message = de.receiveString();
                switch (message){
                    case "add":
                        eio.add(de);break;
                    case "delete": eio.delete(de);break;
                    case "find" : eio.find(de);break;
                    case "change": eio.change(de);break;
                    case "show":
                        eio.show(de);break;
                    case "bye":return;
                }
            }
        }
    
        //对学员进行处理
        private void handleStuManage(StuInformationOperator ioi) throws IOException, ClassNotFoundException {
           while(true){
               String message = de.receiveString();
                switch (message){
                    case "add":
                        ioi.add(de);break;
                    case "delete": ioi.delete(de);break;
                    case "find" : ioi.find(de);break;
                    case "change": ioi.change(de);break;
                    case "show":
                        ioi.show(de);break;
                    case "bye":return;
                }
            }
        }
        
        
        
        
        
        
    }
    
    
    
    
}
